package Model;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.Arrays;


public class RequestHandler 
{	
	private final int SIZE_OF_INT = 4;
	
	private String m_NextAddress;
	private Integer m_NextPort;
	private byte[] payload;
	private String m_Id;
	
	public RequestHandler(byte[] msg) 
	{		
		int startFrom = 1;
		
		byte lenOfAddress = msg[0];
		byte[] address = Arrays.copyOfRange(msg, startFrom, startFrom + lenOfAddress);
		m_NextAddress = new String(address);
		
		startFrom += lenOfAddress;
		
		byte[] port = Arrays.copyOfRange(msg, startFrom, startFrom + SIZE_OF_INT);
		m_NextPort = ByteBuffer.wrap(port).getInt();
		
		startFrom += SIZE_OF_INT;
		
		byte lenOfId = msg[startFrom];
		
		startFrom++;
		
		byte[] id = Arrays.copyOfRange(msg, startFrom, startFrom + lenOfId);
		m_Id = new String(id);
		
		startFrom += lenOfId;
		
		payload = Arrays.copyOfRange(msg, startFrom, msg.length);
	}

	
	public byte[] getMessage() 
	{
		return payload;
	}



	public void send() {
		try {
	         Socket skt = new Socket(m_NextAddress, m_NextPort);
	         DataInputStream in = new DataInputStream(skt.getInputStream());	         

	         DataOutputStream out = new DataOutputStream(skt.getOutputStream());

	         byte[] b = getMessage();
	         
	         out.writeInt(b.length); // write length of the message
	         out.write(b);   
	         
	      // get client's request
			byte[] message = null;
			int length = in.readInt();                    // read length of incoming message
			if(length>0) {
			    message = new byte[length];
			    in.readFully(message, 0, message.length); // read the message
			}

	         out.close();
	         in.close();
	         skt.close();
	         
	         
	         Data.getInstance().add(message, getMapKey());
	                  
	      }
	      catch(Exception e) 
	      {
	    	  System.out.println(e.toString());
	      }
		
	}



	public byte[] getMapKey() 
	{
		return arraysConcatenation(m_Id.getBytes(), m_NextAddress.getBytes());
	}
	
	private byte[] arraysConcatenation(Object... arrays)
	{
		int size = 0;
		for (int i = 0; i < arrays.length; i++) 
		{
			size += ((byte[])arrays[i]).length;
		}
		
		byte[] array = new byte[size];
		
		int counter = 0;
		for (int i = 0; i < arrays.length; i++) 
		{
			System.arraycopy(arrays[i], 0, array, counter, ((byte[])arrays[i]).length);
			counter += ((byte[])arrays[i]).length;
		}		
		
		return array;
	}
}
